import os
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import sys

# 添加项目根目录到系统路径
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../')))

from config.config import DATA_CONFIG

class WeatherDataProcessor:
    """
    天气数据处理类，负责数据清洗、转换和特征工程
    """
    def __init__(self):
        self.raw_data_path = os.path.join(os.path.dirname(__file__), '../../', DATA_CONFIG['raw_data_path'])
        self.processed_data_path = os.path.join(os.path.dirname(__file__), '../../', DATA_CONFIG['processed_data_path'])
        
        # 确保处理后的数据目录存在
        os.makedirs(self.processed_data_path, exist_ok=True)
    
    def load_raw_data(self, data_type):
        """
        加载原始数据
        data_type: 'current', 'forecast', 'historical'
        """
        file_map = {
            'current': 'current_weather_raw.csv',
            'forecast': 'weather_forecast_raw.csv',
            'historical': 'historical_weather_raw.csv'
        }
        
        if data_type not in file_map:
            print(f"未知的数据类型: {data_type}")
            return None
        
        file_path = os.path.join(self.raw_data_path, file_map[data_type])
        if not os.path.exists(file_path):
            print(f"文件不存在: {file_path}")
            return None
        
        try:
            df = pd.read_csv(file_path)
            return df
        except Exception as e:
            print(f"加载数据失败: {e}")
            return None
    
    def clean_data(self, df):
        """
        数据清洗：处理缺失值、异常值等
        """
        if df is None or df.empty:
            return None
        
        # 复制数据，避免修改原始数据
        df_clean = df.copy()
        
        # 处理缺失值
        # 对于温度、湿度等数值型数据，使用中位数填充
        numeric_cols = ['temp', 'temp_min', 'temp_max', 'humidity', 'wind_speed', 'pressure']
        for col in numeric_cols:
            if col in df_clean.columns and df_clean[col].isnull().any():
                median_val = df_clean[col].median()
                df_clean[col].fillna(median_val, inplace=True)
        
        # 对于天气状况等分类数据，使用众数填充
        categorical_cols = ['weather_condition', 'wind_direction', 'city']
        for col in categorical_cols:
            if col in df_clean.columns and df_clean[col].isnull().any():
                mode_val = df_clean[col].mode()[0]
                df_clean[col].fillna(mode_val, inplace=True)
        
        # 处理异常值（使用IQR方法）
        for col in numeric_cols:
            if col in df_clean.columns:
                Q1 = df_clean[col].quantile(0.25)
                Q3 = df_clean[col].quantile(0.75)
                IQR = Q3 - Q1
                lower_bound = Q1 - 1.5 * IQR
                upper_bound = Q3 + 1.5 * IQR
                
                # 将异常值替换为边界值
                df_clean.loc[df_clean[col] < lower_bound, col] = lower_bound
                df_clean.loc[df_clean[col] > upper_bound, col] = upper_bound
        
        return df_clean
    
    def transform_data(self, df):
        """
        数据转换：标准化、归一化、特征工程等
        """
        if df is None or df.empty:
            return None
        
        df_transformed = df.copy()
        
        # 转换时间列为datetime类型
        time_cols = ['timestamp', 'forecast_time']
        for col in time_cols:
            if col in df_transformed.columns and not pd.api.types.is_datetime64_any_dtype(df_transformed[col]):
                df_transformed[col] = pd.to_datetime(df_transformed[col])
        
        # 添加时间特征
        if any(col in df_transformed.columns for col in time_cols):
            time_col = next(col for col in time_cols if col in df_transformed.columns)
            
            # 提取时间特征
            df_transformed['year'] = df_transformed[time_col].dt.year
            df_transformed['month'] = df_transformed[time_col].dt.month
            df_transformed['day'] = df_transformed[time_col].dt.day
            df_transformed['hour'] = df_transformed[time_col].dt.hour
            df_transformed['dayofweek'] = df_transformed[time_col].dt.dayofweek
            
            # 添加季节特征
            df_transformed['season'] = df_transformed['month'].apply(self._get_season)
            
            # 添加是否周末特征
            df_transformed['is_weekend'] = df_transformed['dayofweek'].apply(lambda x: 1 if x >= 5 else 0)
        
        # 添加温差特征
        if 'temp_max' in df_transformed.columns and 'temp_min' in df_transformed.columns:
            df_transformed['temp_range'] = df_transformed['temp_max'] - df_transformed['temp_min']
        
        # 添加体感温度特征（使用温度和湿度计算）
        if 'temp' in df_transformed.columns and 'humidity' in df_transformed.columns:
            df_transformed['feels_like'] = self._calculate_feels_like(df_transformed['temp'], df_transformed['humidity'])
        
        return df_transformed
    
    def _get_season(self, month):
        """
        根据月份确定季节
        """
        if month in [3, 4, 5]:
            return '春季'
        elif month in [6, 7, 8]:
            return '夏季'
        elif month in [9, 10, 11]:
            return '秋季'
        else:  # month in [12, 1, 2]
            return '冬季'
    
    def _calculate_feels_like(self, temp, humidity):
        """
        计算体感温度（简化版）
        """
        # 简化的体感温度计算公式
        return temp + 0.348 * humidity / 100 * 6.105 * np.exp(17.27 * temp / (237.7 + temp)) - 4.25
    
    def process_data(self, data_type):
        """
        处理指定类型的数据并保存
        """
        # 加载原始数据
        df = self.load_raw_data(data_type)
        if df is None:
            return None
        
        # 数据清洗
        df_clean = self.clean_data(df)
        if df_clean is None:
            return None
        
        # 数据转换
        df_transformed = self.transform_data(df_clean)
        if df_transformed is None:
            return None
        
        # 保存处理后的数据
        output_file_map = {
            'current': 'current_weather.csv',
            'forecast': 'weather_forecast.csv',
            'historical': 'historical_weather.csv'
        }
        
        output_path = os.path.join(self.processed_data_path, output_file_map[data_type])
        df_transformed.to_csv(output_path, index=False)
        print(f"处理后的数据已保存至: {output_path}")
        
        return df_transformed
    
    def merge_all_data(self):
        """
        合并所有处理后的数据，用于综合分析
        """
        data_types = ['current', 'forecast', 'historical']
        dfs = []
        
        for data_type in data_types:
            file_path = os.path.join(self.processed_data_path, f"{data_type.replace('_raw', '')}_weather.csv")
            if os.path.exists(file_path):
                try:
                    df = pd.read_csv(file_path)
                    df['data_source'] = data_type  # 添加数据源标识
                    dfs.append(df)
                except Exception as e:
                    print(f"加载 {data_type} 数据失败: {e}")
        
        if not dfs:
            print("没有可用的数据文件")
            return None
        
        # 合并所有数据
        all_data = pd.concat(dfs, ignore_index=True)
        
        # 保存合并后的数据
        output_path = os.path.join(self.processed_data_path, 'all_weather_data.csv')
        all_data.to_csv(output_path, index=False)
        print(f"合并后的数据已保存至: {output_path}")
        
        return all_data
    
    def analyze_data(self, df=None, data_type='all'):
        """
        数据分析：计算统计指标、相关性等
        """
        if df is None:
            # 如果没有提供数据，则加载指定类型的数据
            if data_type == 'all':
                file_path = os.path.join(self.processed_data_path, 'all_weather_data.csv')
            else:
                file_map = {
                    'current': 'current_weather.csv',
                    'forecast': 'weather_forecast.csv',
                    'historical': 'historical_weather.csv'
                }
                if data_type not in file_map:
                    print(f"未知的数据类型: {data_type}")
                    return None
                file_path = os.path.join(self.processed_data_path, file_map[data_type])
            
            if not os.path.exists(file_path):
                print(f"文件不存在: {file_path}")
                return None
            
            try:
                df = pd.read_csv(file_path)
            except Exception as e:
                print(f"加载数据失败: {e}")
                return None
        
        if df.empty:
            print("数据为空")
            return None
        
        # 基本统计分析
        numeric_cols = df.select_dtypes(include=[np.number]).columns.tolist()
        stats = df[numeric_cols].describe()
        
        # 相关性分析
        correlation = df[numeric_cols].corr()
        
        # 按城市分组统计（如果有城市列）
        city_stats = None
        if 'city' in df.columns:
            city_stats = df.groupby('city')['temp'].agg(['mean', 'min', 'max']).reset_index()
            city_stats.columns = ['城市', '平均温度', '最低温度', '最高温度']
        
        # 按天气状况分组统计（如果有天气状况列）
        weather_stats = None
        if 'weather_condition' in df.columns:
            weather_stats = df.groupby('weather_condition').size().reset_index(name='count')
            weather_stats.columns = ['天气状况', '出现次数']
            weather_stats = weather_stats.sort_values('出现次数', ascending=False)
        
        # 返回分析结果
        analysis_results = {
            'basic_stats': stats,
            'correlation': correlation,
            'city_stats': city_stats,
            'weather_stats': weather_stats
        }
        
        return analysis_results